home *** CD-ROM | disk | FTP | other *** search
/ Apple WWDC 1996 / WWDC96_1996 (CD).toast / Technology Materials / MacApp Release 10 / MacApp Release 10 - HD Ready / Libraries / Core / Sources / CWDebug.cp < prev    next >
Encoding:
Text File  |  1996-04-03  |  17.4 KB  |  612 lines  |  [TEXT/MPS ]

  1. //----------------------------------------------------------------------------------------
  2. // CWDebug.cp
  3. // Copyright © 1984-96 by Apple Computer, Inc. All rights reserved.
  4. //----------------------------------------------------------------------------------------
  5.  
  6. #if defined(__MWERKS__)
  7.  
  8. // Metrowerks
  9.  
  10. #ifndef __CWDEBUG__
  11. #include "CWDebug.h"
  12. #endif
  13.  
  14. #ifndef __CONSOLE__
  15. #include <console.h>
  16. #endif
  17.  
  18. #ifndef __SIOUX__
  19. #include <SIOUX.h>
  20. #endif
  21.  
  22. #if (qDebug || qTheDebugger)
  23.  
  24. // MacApp
  25.  
  26. #ifndef __UDEBUG__
  27. #include "UDebug.h"
  28. #endif
  29.  
  30. #ifndef __UFAILURE__
  31. #include "UFailure.h"
  32. #endif
  33.  
  34. // Toolbox
  35.  
  36. #ifndef __APPLEEVENTS__
  37. #include <AppleEvents.h>
  38. #endif
  39.  
  40. #ifndef __AEREGISTRY__
  41. #include <AERegistry.h>
  42. #endif
  43.  
  44. #ifndef __AEOBJECTS__
  45. #include <AEObjects.h>
  46. #endif
  47.  
  48. #ifndef __AEOBJECTPACKING__
  49. #include <AEPackObject.h>
  50. #endif
  51.  
  52. // ANSI
  53.  
  54. #ifndef __STDIO__
  55. #include <stdio.h>
  56. #endif
  57.  
  58.  
  59. //========================================================================================
  60. // GLOBAL Procedures
  61. //========================================================================================
  62. #undef Inherited
  63.  
  64. /****************************************************************
  65.  
  66.     The following is support for debugging with CW builds
  67.     Mark Anderson
  68.     metrowerks
  69.     1/2/95
  70.     
  71.     InitUDebug has been changed slightly so that it sets 
  72.     a variable which indicates which debugger is being used.
  73.     If a debugger is being used that supports output to a 
  74.     console-type window, as with MWDebug or Jasik, the following 
  75.     code will do that.  You can manually override this default 
  76.     behavior in one of 2 ways.  If you want to use SIOUX for output, 
  77.     you will need to add the SIOUX library to your project and set 
  78.     TypeOfCWDebugging to equal kxUseSIOUX. (TypeOfCWDebugging is set in 
  79.     CWDebug.h.)  If you want your debugger to always use the AppleEvent 
  80.     method of reporting, set TypeOfCWDebugging to kxUseSTE. 
  81.     
  82.     MacApp has trouble with SIOUX because its window isn't 
  83.     part of the MacApp controlled window list.  Consequently
  84.     window activation can get confused.  We leave it in because 
  85.     it is an alternative.  Perhaps MacApp will someday be 
  86.     friendlier to non-MacApp windows.    
  87.     
  88.     If the Debugger Nub is running (MetroNUB, Debug Services, etc.),
  89.     you must have an appropriate debugger running that can 
  90.     intercept the SysBreakStrs.  You must also have STE open 
  91.     if you intend to use the AppleEvent hack.  Even though
  92.     SourceBug can't currently read CW Sym files, you can use 
  93.     it to output to if you want but it is a little funky.
  94.     
  95. ****************************************************************/
  96.  
  97. long AEfprintf(char *buffer, long n);
  98.     
  99. #pragma segment GDebug
  100.  
  101. //----------------------------------------------------------------------------------------
  102. // InitCWDebug:
  103. //----------------------------------------------------------------------------------------
  104.  
  105. void InitCWDebug()
  106. {
  107. #if TypeOfCWDebugging == kxUseSIOUX
  108.     // Please see SIOUX.h for the meanings of these fields
  109.     SIOUXSettings.initializeTB = FALSE;
  110.     SIOUXSettings.setupmenus = FALSE;
  111.     SIOUXSettings.autocloseonquit = TRUE;
  112.     SIOUXSettings.asktosaveonclose = TRUE;
  113.     SIOUXSettings.showstatusline = FALSE;
  114.     SIOUXSettings.tabspaces = 0;
  115.     SIOUXSettings.columns = 80;
  116.     SIOUXSettings.rows = 24;
  117.     SIOUXSettings.toppixel = 0;
  118.     SIOUXSettings.leftpixel = 0;
  119.     SIOUXSettings.fontid = monaco;
  120.     SIOUXSettings.fontsize = 9;
  121.     SIOUXSettings.fontface = normal;
  122. #endif
  123.  
  124.     setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
  125. }
  126.  
  127. #if TypeOfCWDebugging == kxUseSIOUX
  128. short CWDebugHandleOneEvent(struct EventRecord* userevent)
  129. {
  130.     return SIOUXHandleOneEvent(userevent);
  131. }
  132. #else
  133. short CWDebugHandleOneEvent(struct EventRecord* /*userevent*/)
  134. {
  135.     return 0;
  136. }
  137. #endif
  138.  
  139. #if TypeOfCWDebugging != kxUseSIOUX
  140.     
  141. short InstallConsole(short /* fd */)
  142. {
  143.     return noErr;
  144. }
  145.  
  146. long WriteCharsToConsole(char *buffer, long n)
  147. {
  148.     if (n > 0)
  149.     {
  150. #if TypeOfCWDebugging == kxUseSTE
  151.         return AEfprintf(buffer, n);
  152. #endif
  153.             DebugWriteLnHook(buffer, n);
  154.             return n;
  155.         }
  156.     return 0;
  157. }
  158.  
  159. long ReadCharsFromConsole(char * /* buffer */, long /* n */)
  160. {
  161.     return 0;
  162. }
  163.  
  164. //========================================================================================
  165. // CLASS XAEApplication
  166. //========================================================================================
  167.  
  168. // The following code is for sending AppleEvents to Scriptable Text Editor
  169.  
  170. class XAEApplication
  171. {
  172. protected:
  173.     AEDesc        fAppObj;
  174. public:
  175.     XAEApplication( void );
  176.     ~XAEApplication( void );
  177.     virtual AEDesc * GetObject(void) { return &fAppObj; }    
  178. };
  179.  
  180. //========================================================================================
  181. // CLASS XAEWindow
  182. //========================================================================================
  183.  
  184. class XAEWindow : public XAEApplication
  185. {
  186. protected:
  187.     AEDesc        fWindObj;
  188. public:
  189.  
  190.     XAEWindow( void );
  191.     ~XAEWindow( void );
  192.     virtual AEDesc * GetObject(void) { return &fWindObj; }    
  193. };
  194.  
  195. //========================================================================================
  196. // CLASS XAEParagraph
  197. //========================================================================================
  198.  
  199. class XAEParagraph : public XAEWindow
  200. {
  201. protected:
  202.     AEDesc        fParaObj;
  203. public:
  204.     XAEParagraph() { ProgramBreak("XAEParagraph called without parameters");}
  205.     XAEParagraph(  long windowNumber );
  206.     ~XAEParagraph( void );
  207.     virtual AEDesc * GetObject(void) { return &fParaObj; }    
  208. };
  209.  
  210. //========================================================================================
  211. // CLASS XAppleEvent
  212. //========================================================================================
  213.  
  214. class XAppleEvent
  215. {
  216.     AppleEvent         fEvent;
  217. public:
  218.     XAppleEvent() { ProgramBreak("XAppleEvent called without parameters");}
  219.     XAppleEvent( OSType appid, OSType eventclass, OSType eventid );
  220.     XAppleEvent( OSType appid, OSType eventclass, OSType eventid, XAEApplication* directObject );
  221.     OSErr    AddIndirectObject( AEKeyword theKeyword, DescType type, Ptr thing, Size size );
  222.     OSErr     Send();
  223.     OSErr    GetResponseFromReply( OSType desiredType, Ptr thing, Size size );
  224.     long    GetNumOfThings( void );
  225.     Boolean    DoesThingExist( void );
  226.     ~XAppleEvent(void);    
  227. };
  228.  
  229. //constants
  230. const    long    badReturnValue = -1L;
  231.  
  232. //prototypes
  233. Boolean sendMessageToWrite (OSType appid, OSType eventclass, OSType eventid, char * tmp) ;
  234. Boolean FindAProcess( OSType signature );
  235. Boolean AppleEventsAvailable( void );
  236.  
  237. //----------------------------------------------------------------------------------------
  238. // XAppleEvent::XAppleEvent:
  239. //----------------------------------------------------------------------------------------
  240. #pragma segment GDebug
  241.  
  242. XAppleEvent::XAppleEvent( OSType appid, OSType eventclass, OSType eventid )
  243. {
  244.     AEAddressDesc     address = {typeNull, nil}; 
  245.     OSErr            err;
  246.  
  247.     fEvent.descriptorType = typeNull; 
  248.     fEvent.dataHandle = nil; 
  249.     
  250.     err = AECreateDesc (typeApplSignature, (Ptr) &appid, sizeof (appid), &address);
  251.     if ( err == noErr )
  252.         err = AECreateAppleEvent ( eventclass, eventid, &address, 0, 0, &fEvent);
  253.     if ( err != noErr )
  254.         ProgramBreak("Failed in XAppleEvent constructor");    
  255.  
  256.     AEDisposeDesc (&address);        
  257.     
  258. }
  259.  
  260. //----------------------------------------------------------------------------------------
  261. // XAppleEvent::XAppleEvent:
  262. //----------------------------------------------------------------------------------------
  263.  
  264. XAppleEvent::XAppleEvent( OSType appid, OSType eventclass, OSType eventid, XAEApplication* directObject )
  265. {
  266.     AEAddressDesc     address = {typeNull, nil}; 
  267.     OSErr            err;
  268.  
  269.     fEvent.descriptorType = typeNull; 
  270.     fEvent.dataHandle = nil; 
  271.     
  272.     err = AECreateDesc (typeApplSignature, (Ptr) &appid, sizeof (appid), &address);
  273.     if ( err == noErr )
  274.         err = AECreateAppleEvent ( eventclass, eventid, &address, 0, 0, &fEvent);
  275.     if ( err == noErr )
  276.         err = AEPutParamDesc (&fEvent, keyDirectObject, directObject->GetObject() );
  277.     if ( err != noErr )
  278.         ProgramBreak("Failed in XAppleEvent constructor");    
  279.  
  280.     AEDisposeDesc (&address);        
  281.     
  282. }
  283.  
  284. //----------------------------------------------------------------------------------------
  285. // XAppleEvent::AddIndirectObject:
  286. //----------------------------------------------------------------------------------------
  287.  
  288. OSErr XAppleEvent::AddIndirectObject( AEKeyword theKeyword, DescType type, Ptr thing, Size size )
  289. {
  290.     OSErr            err;
  291.     AEDesc            indirect = {typeNull, nil};
  292.     
  293.     
  294.     err = AECreateDesc(type, thing, size, &indirect);
  295.  
  296.     if ( err == noErr )
  297.         err = AEPutParamDesc (&fEvent, theKeyword, &indirect);    
  298.                     
  299.     if ( err != noErr )
  300.         ProgramBreak("Failed in AddIndirectObject");
  301.  
  302.     AEDisposeDesc (&indirect);    
  303.     
  304.     return err;    
  305. }
  306.  
  307. //----------------------------------------------------------------------------------------
  308. // XAppleEvent::Send:
  309. //----------------------------------------------------------------------------------------
  310.  
  311. OSErr XAppleEvent::Send( void )
  312. {
  313.     AppleEvent         reply = {typeNull, nil};
  314.     OSErr            err;
  315.     
  316.         err = AESend ( &fEvent, &reply,  kAENoReply , kAENormalPriority,  kNoTimeOut, nil, nil);    
  317.  
  318.     AEDisposeDesc (&reply);        
  319.     return err;
  320. }
  321.  
  322. //----------------------------------------------------------------------------------------
  323. // XAppleEvent::~XAppleEvent:
  324. //----------------------------------------------------------------------------------------
  325.  
  326. XAppleEvent::~XAppleEvent( void )
  327. {
  328.     AEDisposeDesc (&fEvent);            
  329. }
  330.  
  331. //----------------------------------------------------------------------------------------
  332. // XAppleEvent::GetResponseFromReply:
  333. //----------------------------------------------------------------------------------------
  334.  
  335. OSErr XAppleEvent::GetResponseFromReply( OSType desiredType, Ptr thing, Size size )
  336. {
  337.  
  338.     AppleEvent         reply = {typeNull, nil};
  339.     OSErr             err;
  340.     DescType         actualtype;
  341.     Size             actualsize;
  342.  
  343.  
  344.     err = AESend ( &fEvent, &reply,  kAEWaitReply + kAENeverInteract, 
  345.                                         kAENormalPriority,  120, nil, nil);    
  346.     if ( err == noErr )
  347.         err = AEGetParamPtr ( &reply, keyDirectObject, desiredType,         
  348.                         &actualtype, thing, size, &actualsize);
  349.     if ( err != noErr )
  350.         ProgramBreak("Failed in GetResponseFromReply");
  351.         
  352.  
  353.     AEDisposeDesc (&reply);    
  354.     
  355.     return err;        
  356. }
  357.  
  358. //----------------------------------------------------------------------------------------
  359. // XAppleEvent::GetNumOfThings:
  360. //----------------------------------------------------------------------------------------
  361.  
  362. long XAppleEvent::GetNumOfThings( void )
  363. {
  364.  
  365.     OSErr             err;
  366.     long            things = badReturnValue;
  367.  
  368.     err = GetResponseFromReply( typeLongInteger, (Ptr) &things, sizeof (things) );
  369.  
  370.     if ( err != noErr )
  371.         ProgramBreak("Failed in GetNumOfThings");
  372.     
  373.     return things;        
  374. }
  375.  
  376. //----------------------------------------------------------------------------------------
  377. // XAppleEvent::DoesThingExist:
  378. //----------------------------------------------------------------------------------------
  379.  
  380. Boolean XAppleEvent::DoesThingExist( void )
  381. {
  382.  
  383.     OSErr             err;
  384.     Boolean            thingExists = false;
  385.  
  386.     err = GetResponseFromReply( typeBoolean, (Ptr) &thingExists, sizeof (thingExists) );
  387.  
  388.     if ( err != noErr )
  389.         ProgramBreak("Failed in DoesThingExist");
  390.     
  391.     return thingExists;        
  392. }
  393.  
  394. //----------------------------------------------------------------------------------------
  395. // XAEApplication::XAEApplication:
  396. //----------------------------------------------------------------------------------------
  397.  
  398. XAEApplication::XAEApplication ( void )
  399. {
  400.  
  401.     fAppObj.descriptorType = typeNull; 
  402.     fAppObj.dataHandle = nil; 
  403.  
  404. }
  405.  
  406. //----------------------------------------------------------------------------------------
  407. // XAEApplication::~XAEApplication:
  408. //----------------------------------------------------------------------------------------
  409.  
  410. XAEApplication::~XAEApplication(void) 
  411.  { 
  412.  
  413.     AEDisposeDesc (&fAppObj);
  414.  
  415.  }
  416.  
  417. //----------------------------------------------------------------------------------------
  418. // XAEWindow::XAEWindow:
  419. //----------------------------------------------------------------------------------------
  420.  
  421. XAEWindow::XAEWindow ( void ) : XAEApplication( )
  422. {
  423.     OSErr        myErr;
  424.     AEDesc       windNumDesc = {typeNull, nil}; 
  425.     long         windowNumber;
  426.     
  427.     fWindObj.descriptorType = typeNull; 
  428.     fWindObj.dataHandle = nil; 
  429.     //we only deal with the frontmost window 
  430.     windowNumber = 1;
  431.     //the container is Null
  432.     myErr = AECreateDesc(typeLongInteger,(Ptr)&windowNumber, sizeof(windowNumber), &windNumDesc);
  433.     myErr = CreateObjSpecifier ( cWindow, &fAppObj, formAbsolutePosition, &windNumDesc, true, &fWindObj );
  434.  
  435. }
  436.  
  437. //----------------------------------------------------------------------------------------
  438. // XAEWindow::~XAEWindow:
  439. //----------------------------------------------------------------------------------------
  440.  
  441. XAEWindow::~XAEWindow(void) 
  442.  { 
  443.  
  444.     AEDisposeDesc (&fWindObj);
  445.  
  446.  }
  447.  
  448. //----------------------------------------------------------------------------------------
  449. // XAEParagraph::XAEParagraph:
  450. //----------------------------------------------------------------------------------------
  451.  
  452. XAEParagraph::XAEParagraph ( long paraNumber ) : XAEWindow( )
  453. {
  454.  
  455.     OSErr        myErr;
  456.     AEDesc       paraNumDesc = {typeNull, nil}; 
  457.  
  458.     fParaObj.descriptorType = typeNull; 
  459.     fParaObj.dataHandle = nil; 
  460.     //the container is Null
  461.     myErr = AECreateDesc(typeLongInteger,(Ptr)¶Number, sizeof(paraNumber), ¶NumDesc);
  462.     myErr = CreateObjSpecifier ( cParagraph, &fWindObj, formAbsolutePosition, ¶NumDesc, true, &fParaObj );
  463.  
  464. }
  465.  
  466. //----------------------------------------------------------------------------------------
  467. // XAEParagraph::~XAEParagraph:
  468. //----------------------------------------------------------------------------------------
  469.  
  470. XAEParagraph::~XAEParagraph(void) 
  471.  { 
  472.     AEDisposeDesc (&fParaObj);     
  473.  }
  474.  
  475. //========================================================================================
  476. // GLOBAL Procedures
  477. //========================================================================================
  478.  
  479. //----------------------------------------------------------------------------------------
  480. // sendMessageToWrite:
  481. //----------------------------------------------------------------------------------------
  482.  
  483. Boolean sendMessageToWrite (OSType appid, OSType eventclass, OSType eventid, char * txt) 
  484. {
  485.     
  486.     long            paragraphNum;
  487.     Boolean            result = false;
  488.     OSErr             err;
  489.     OSType            indirect = cParagraph;
  490.     
  491.     XAEWindow        windObj;
  492.     XAppleEvent        count( appid,  kAECoreSuite, kAECountElements, &windObj );
  493.     count.AddIndirectObject( keyAEObjectClass, typeType, (Ptr)&indirect, sizeof(indirect) );
  494.     paragraphNum = count.GetNumOfThings();
  495.  
  496.     if ( paragraphNum != badReturnValue )
  497.     {
  498.                 //make an apple event for changing the text in the last paragraph
  499.         XAEParagraph    paraObj( paragraphNum );
  500.         XAppleEvent        writeIt( appid, eventclass, eventid, ¶Obj );
  501.         writeIt.AddIndirectObject( keyAEData, typeChar, txt, strlen(txt) );
  502.         err = writeIt.Send();
  503.         if (noErr == err )
  504.         {
  505.             //make a apple event for selecting the text in the last paragraph (so it scrolls)
  506.             paragraphNum = count.GetNumOfThings();// call because the number of paras has changed
  507.             XAEParagraph    paraObj2( paragraphNum - 1 );    //we want to select the last line
  508.                                                             //with a word; not the return character
  509.             XAppleEvent    selectIt( appid,  kAEMiscStandards,  kAESelect, ¶Obj2 );
  510.             err = selectIt.Send();
  511.         }
  512.     }
  513.     
  514.     return noErr == err;
  515.  
  516. } /*sendMessageToWrite*/
  517.  
  518. //----------------------------------------------------------------------------------------
  519. // FindAProcess:
  520. //----------------------------------------------------------------------------------------
  521.  
  522. Boolean FindAProcess( OSType signature )
  523. {
  524.     Boolean                result = false;
  525.     ProcessSerialNumber    PSN;
  526.     ProcessInfoRec        infoRec;
  527.     PSN.highLongOfPSN = 0;
  528.     PSN.lowLongOfPSN = kNoProcess;
  529.     OSType                 application = 'APPL';
  530.     infoRec.processInfoLength = sizeof(ProcessInfoRec);
  531.     infoRec.processName = nil;
  532.     infoRec.processAppSpec = nil;
  533.  
  534.     while (GetNextProcess( &PSN ) == noErr )
  535.     {
  536.         if ( GetProcessInformation( &PSN, &infoRec ) == noErr )
  537.             if ( (infoRec.processType == application) && 
  538.                 (infoRec.processSignature == signature ) )
  539.             {
  540.                 result = true;
  541.                 break;
  542.             }
  543.     }    
  544.     return result;
  545. }
  546.  
  547. //----------------------------------------------------------------------------------------
  548. // AEfprintf:
  549. //----------------------------------------------------------------------------------------
  550.  
  551. long AEfprintf(char *buffer, long byteCount)
  552. {
  553.  
  554.     char            debugStr[256];        
  555.     static Boolean    firstTime = true;
  556.     OSType    signature = 'quil';     //Although this code doesn't use unusual AEs (mostly from 
  557.                                     //core suite), the only app I know that will work is Scriptable 
  558.                                     //Text Editor (which you will find on the CD with the AppleScript
  559.                                     //installation stuff).
  560.  
  561.     memcpy(debugStr, buffer, (size_t) byteCount);
  562.     debugStr[byteCount] = 0;
  563.             
  564.     if ( !FindAProcess( signature )  )
  565.     {
  566.         if (firstTime)
  567.         {
  568.             ProgramBreak( "\pLaunch Scriptable Text Editor to display Debug Messages, etc." );
  569.              firstTime = false;
  570.         }
  571.         return byteCount;
  572.     }
  573.     //well, it's running, but does it currently have a window?   
  574.     XAEWindow        windObj; //looking for a window
  575.     XAppleEvent     exists( signature,  kAECoreSuite, kAEDoObjectsExist, &windObj );
  576.  
  577.     if ( !exists.DoesThingExist() )
  578.     {
  579.     //The app's running but there isn't a window.  Let's make it easy and open one ourselves.
  580.         OSType             indirect = cWindow;
  581.         //This AE doesn't have a direct parameter
  582.         XAppleEvent     make( signature,  kAECoreSuite, kAECreateElement );
  583.         make.AddIndirectObject( keyAEObjectClass, typeType, (Ptr)&indirect, sizeof(indirect) );
  584.         if (make.Send())
  585.         {
  586.             ProgramBreak( "\pWasn't able to make a window for STE." );
  587.             return byteCount;
  588.         }
  589.     }
  590.     
  591.     sendMessageToWrite ( signature , kAECoreSuite, kAESetData, debugStr );
  592.     
  593.     return byteCount;
  594. }        
  595.     
  596. #endif //OnlyUseSIOUX
  597. #endif //(qDebug || qTheDebugger)
  598.  
  599. #if TypeOfCWDebugging != kxUseSIOUX    
  600. void RemoveConsole(void)
  601. {
  602.     return;
  603. }
  604. #endif
  605.  
  606. #endif // defined(__MWERKS__)
  607.  
  608. //----------------------------------------------------------------------------------------
  609. // End of CWDebug.cp
  610.  
  611. #pragma segment Inline
  612.